﻿using LeoK.Common;
using LeoK.DCI.Bll;
using LeoK.DCI.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Input;
using System.Windows.Media;
using Telerik.Charting;
using Telerik.Windows.Controls.ChartView;

namespace LeoK.DCI.Views
{
    /// <summary>
    /// DCIChart.xaml 的交互逻辑
    /// </summary>
    public partial class DCIChart : INotifyPropertyChanged
    {
        private List<DCI_DayLine> _dayLines;
        public List<DCI_DayLine> DayLines
        {
            get { return _dayLines; }
            set
            {
                _dayLines = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("DayLines"));
                }
            }
        }

        private List<MACDData> _macdDatas;
        public List<MACDData> MACDDatas
        {
            get { return _macdDatas; }
            set
            {
                _macdDatas = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("MACDDatas"));
                }
            }
        }

        public DCIChart()
        {
            InitializeComponent();

            DataContext = this;
            LoadData();
        }
        
        public async void LoadData()
        {
            try
            {
                DayLines = await DCIManager.GetDayLines();
                SetAxis(DayLines);

                slineMA7.ItemsSource = DCIManager.GetMA(DayLines, 7);
                slineMA30.ItemsSource = DCIManager.GetMA(DayLines, 30);
                slineMA120.ItemsSource = DCIManager.GetMA(DayLines, 120);
                slineMA360.ItemsSource = DCIManager.GetMA(DayLines, 360);

                //chart.HorizontalZoomRangeStart = (DayLines.Count - 120.0) / DayLines.Count;

                MACDDatas = DCIManager.GetMACDData(DayLines);
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex);
            }

        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RadCartesianChart_OnMouseMove(object sender, MouseEventArgs e)
        {
            try
            {
                DataTuple d = chart.ConvertPointToData(e.GetPosition(chart), HAxis, VAxis);

                if (d != null && d.FirstValue != null && d.SecondValue != null)
                {
                    VAGridLineAnnotation.Value = d.SecondValue;
                    VAGridLineAnnotation.Label = (Math.Round((double)d.SecondValue, 2)).ToString();
                    HAGridLineAnnotation.Value = d.FirstValue;
                    HAGridLineAnnotation.Label = ((DateTime)d.FirstValue).ToString("MM/dd");
                    SetMaLable((DateTime)d.FirstValue);
                    SetLable((DateTime)d.FirstValue);
                }
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex);
            }
        }

        private void SetMaLable(DateTime date)
        {
            MAData m7Data = (slineMA7.ItemsSource as List<MAData>).FirstOrDefault(p => p.Date.ToString("yyyyMMdd") == date.ToString("yyyyMMdd"));
            if (m7Data != null)
            {
                tbMA7.Text = "MA7:" + Math.Round(m7Data.Value, 2);
            }

            MAData m30Data = (slineMA30.ItemsSource as List<MAData>).FirstOrDefault(p => p.Date.ToString("yyyyMMdd") == date.ToString("yyyyMMdd"));
            if (m30Data != null)
            {
                tbMA30.Text = "MA30:" + Math.Round(m30Data.Value, 2);
            }

            MAData m120Data = (slineMA120.ItemsSource as List<MAData>).FirstOrDefault(p => p.Date.ToString("yyyyMMdd") == date.ToString("yyyyMMdd"));
            if (m120Data != null)
            {
                tbMA120.Text = "MA120:" + Math.Round(m120Data.Value, 2);
            }

            MAData m360Data = (slineMA360.ItemsSource as List<MAData>).FirstOrDefault(p => p.Date.ToString("yyyyMMdd") == date.ToString("yyyyMMdd"));
            if (m360Data != null)
            {
                tbMA360.Text = "MA360:" + Math.Round(m360Data.Value, 2);
            }
        }

        private void SetLable(DateTime date)
        {
            tbOpen.Foreground = new SolidColorBrush(Colors.Red);
            tbClose.Foreground = new SolidColorBrush(Colors.Red);
            tbHigh.Foreground = new SolidColorBrush(Colors.Red);
            tbLow.Foreground = new SolidColorBrush(Colors.Red);
            tbDiff.Foreground = new SolidColorBrush(Colors.Red);

            DCI_DayLine dayLine = DayLines.FirstOrDefault(p => p.Date.ToString("yyyyMMdd") == date.ToString("yyyyMMdd"));
            if (dayLine != null)
            {
                tbOpen.Text = date.ToString("yyyy/MM/dd dddd") + "  开盘：" + Math.Round(dayLine.Open, 2);
                tbClose.Text = "收盘：" + Math.Round(dayLine.Close, 2);
                tbHigh.Text = "最高：" + Math.Round(dayLine.High, 2);
                tbLow.Text = "最低" + Math.Round(dayLine.Low, 2);
                tbDiff.Text = "幅度：" + Math.Round(dayLine.Close - dayLine.PreClose, 2) + "(" + Math.Round((dayLine.Close - dayLine.PreClose)/dayLine.PreClose*100, 2) + "%)";

                if (dayLine.PreClose > dayLine.Close)
                {
                    tbOpen.Foreground = new SolidColorBrush(Colors.Green);
                    tbClose.Foreground = new SolidColorBrush(Colors.Green);
                    tbHigh.Foreground = new SolidColorBrush(Colors.Green);
                    tbLow.Foreground = new SolidColorBrush(Colors.Green);
                    tbDiff.Foreground = new SolidColorBrush(Colors.Green);
                }
            }
        }

        private void btnEdit_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            try
            {
                DCIEditor editor = new DCIEditor();
                editor.Closed += (o, args) => LoadData();
                editor.ShowDialog();
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex);
            }
        }

        private void Chart_OnPanOffsetChanged(object sender, ChartPanOffsetChangedEventArgs e)
        {
            try
            {
                int startIndex = (int)(chart.HorizontalZoomRangeStart * DayLines.Count);
                int endIndex = (int)(chart.HorizontalZoomRangeEnd * DayLines.Count);

                if (startIndex < 0)
                {
                    startIndex = 0;
                }
                if (endIndex > DayLines.Count - 1)
                {
                    endIndex = DayLines.Count - 1;
                }

                List<DCI_DayLine> showDayLines = DayLines.GetRange(startIndex, endIndex - startIndex);
                SetAxis(showDayLines);
            }
            catch (Exception ex)
            {
                LogHelper.LogError(ex);
            }
        }

        private void SetAxis(List<DCI_DayLine> dayLines)
        {
            if (dayLines.Count == 0) return;

            VAxis.Maximum = dayLines.Max(p => p.High);
            VAxis.Minimum = dayLines.Min(p => p.Low);
            VAxis.MajorStep = (VAxis.Maximum - VAxis.Minimum) * 0.05;

            double open = dayLines[0].Open;
            double maxPrecent = (VAxis.Maximum - open) / open;
            double minPrecent = (VAxis.Minimum - open) / open;

            PrecentVAxis.Maximum = maxPrecent;
            PrecentVAxis.Minimum = minPrecent;
            PrecentVAxis.MajorStep = Math.Abs(PrecentVAxis.Maximum - PrecentVAxis.Minimum) * 0.05;
        }
    }
}
